// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraPawn.h"

// 包含头文件

#include "GameFramework/Controller.h"
#include "LyraLogChannels.h"
#include "Net/UnrealNetwork.h"
#include "UObject/ScriptInterface.h"

// 包含必要的依赖头文件

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraPawn)

// 包含内联生成的代码

class FLifetimeProperty;
class UObject;

// 前向声明

ALyraPawn::ALyraPawn(const FObjectInitializer& ObjectInitializer)
    : Super(ObjectInitializer)
{
}

// 构造函数实现，调用父类构造函数

void ALyraPawn::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);

    // 调用父类的复制属性获取

    DOREPLIFETIME(ThisClass, MyTeamID);

    // 注册MyTeamID属性为复制属性
}

void ALyraPawn::PreInitializeComponents()
{
    Super::PreInitializeComponents();

    // 调用父类的组件预初始化方法
}

void ALyraPawn::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
    Super::EndPlay(EndPlayReason);

    // 调用父类的游戏结束处理方法
}

void ALyraPawn::PossessedBy(AController* NewController)
{
    const FGenericTeamId OldTeamID = MyTeamID;

    // 保存旧的团队ID

    Super::PossessedBy(NewController);

    // 调用父类的被控制器控制方法

    // Grab the current team ID and listen for future changes
    if (ILyraTeamAgentInterface* ControllerAsTeamProvider = Cast<ILyraTeamAgentInterface>(NewController))
    {
        // 如果新控制器实现了团队代理接口
        MyTeamID = ControllerAsTeamProvider->GetGenericTeamId();

        // 从控制器获取团队ID
        ControllerAsTeamProvider->GetTeamChangedDelegateChecked().AddDynamic(this, &ThisClass::OnControllerChangedTeam);

        // 监听控制器团队变化的委托
    }
    ConditionalBroadcastTeamChanged(this, OldTeamID, MyTeamID);

    // 条件性地广播团队变化
}

void ALyraPawn::UnPossessed()
{
    AController* const OldController = Controller;

    // 保存旧的控制器引用

    // Stop listening for changes from the old controller
    const FGenericTeamId OldTeamID = MyTeamID;

    // 保存旧的团队ID
    if (ILyraTeamAgentInterface* ControllerAsTeamProvider = Cast<ILyraTeamAgentInterface>(OldController))
    {
        ControllerAsTeamProvider->GetTeamChangedDelegateChecked().RemoveAll(this);

        // 移除对旧控制器团队变化的所有监听
    }

    Super::UnPossessed();

    // 调用父类的取消控制方法

    // Determine what the new team ID should be afterwards
    MyTeamID = DetermineNewTeamAfterPossessionEnds(OldTeamID);

    // 确定控制结束后的新团队ID
    ConditionalBroadcastTeamChanged(this, OldTeamID, MyTeamID);

    // 条件性地广播团队变化
}

void ALyraPawn::SetGenericTeamId(const FGenericTeamId& NewTeamID)
{
    if (GetController() == nullptr)
    {
        // 如果没有控制器（未被控制）
        if (HasAuthority())
        {
            // 如果在权威端（服务器）
            const FGenericTeamId OldTeamID = MyTeamID;
            MyTeamID = NewTeamID;
            ConditionalBroadcastTeamChanged(this, OldTeamID, MyTeamID);

            // 设置新团队ID并广播变化
        }
        else
        {
            UE_LOG(LogLyraTeams, Error, TEXT("You can't set the team ID on a pawn (%s) except on the authority"), *GetPathNameSafe(this));

            // 记录错误：只能在权威端设置团队ID
        }
    }
    else
    {
        UE_LOG(LogLyraTeams, Error, TEXT("You can't set the team ID on a possessed pawn (%s); it's driven by the associated controller"), *GetPathNameSafe(this));

        // 记录错误：被控制的Pawn的团队ID由控制器驱动
    }
}

FGenericTeamId ALyraPawn::GetGenericTeamId() const
{
    return MyTeamID;

    // 返回当前团队ID
}

FOnLyraTeamIndexChangedDelegate* ALyraPawn::GetOnTeamIndexChangedDelegate()
{
    return &OnTeamChangedDelegate;

    // 返回团队变化委托的指针
}

void ALyraPawn::OnControllerChangedTeam(UObject* TeamAgent, int32 OldTeam, int32 NewTeam)
{
    const FGenericTeamId MyOldTeamID = MyTeamID;
    MyTeamID = IntegerToGenericTeamId(NewTeam);

    // 将整数团队ID转换为通用团队ID
    ConditionalBroadcastTeamChanged(this, MyOldTeamID, MyTeamID);

    // 条件性地广播团队变化
}

void ALyraPawn::OnRep_MyTeamID(FGenericTeamId OldTeamID)
{
    ConditionalBroadcastTeamChanged(this, OldTeamID, MyTeamID);

    // 当MyTeamID在客户端复制时，广播团队变化
}